let wssUrl = 'wss://emp.emeipaiglobal.com/wss'; // 接口Api，图片地址等等配置，可根据自身情况引入，也可以直接在下面url填入你的 webSocket连接地址

import { ref } from 'vue';

class socketIO {
  constructor(data, time, url) {
    this.socketTask = null;
    this.is_open_socket = ref(false); //避免重复连接
    this.url = url ? url : wssUrl; //连接地址

    this.data = data ? data : null;
    this.connectNum = 1; // 重连次数
    this.traderDetailIndex = 100; // traderDetailIndex ==2 重连
    this.accountStateIndex = 100; // accountStateIndex ==1 重连
    this.followFlake = false; // followFlake == true 重连
    this.init = false;
    //心跳检测
    this.timeout = time ? time : 20000; //多少秒执行检测
    this.heartbeatInterval = null; //检测服务器端是否还活着
    this.reconnectTimeOut = null; //重连之后多久再次重连
    this.networkStatus = true;
    this.isClose = true;
  }

  CALLBACK = (res) => {
    if (res.isConnected) {
      this.traderDetailIndex = 2;
      this.connectSocketInit({ type: 'ping' });
    }
  };

  // 进入这个页面的时候创建websocket连接【整个页面随时使用】
  connectSocketInit(data) {
    console.log('开始初始化WebSocket连接，当前状态：', {
      isClose: this.isClose,
      is_open_socket: this.is_open_socket.value,
      networkStatus: this.networkStatus,
      connectNum: this.connectNum,
      url: this.url
    });
    this.isClose = false;
    this.data = data;
    this.socketTask = uni.connectSocket({
      url: this.url,
      success: () => {
        console.info('正准备建立websocket中...', this.url);
        console.log('WebSocket连接创建成功，等待连接打开');
        // 返回实例
        return this.socketTask;
      },
      fail: (err) => {
        console.error('WebSocket连接创建失败：', err);
        uni.$emit('socketStatus', false);
        uni.$emit('connectError', { type: 'init_fail', error: err });
        console.log('触发socketStatus事件：false，连接失败');
      }
    });
    this.socketTask.onOpen((res) => {
      console.log('WebSocket连接已打开：', res);
      uni.$emit('socketStatus', true);
      console.log('触发socketStatus事件：true，连接成功');
      if (!this.networkStatus) {
        // 连接成功后取消网络监听
        uni.offNetworkStatusChange(this.CALLBACK);
        console.log('取消网络状态监听');
      }
      this.networkStatus = true;
      this.connectNum = 1;
      console.info('WebSocket连接正常！');
      this.send(data);
      console.log('发送初始化数据：', data);
      clearInterval(this.reconnectTimeOut);
      clearInterval(this.heartbeatInterval);
      this.is_open_socket = true;
      console.log('WebSocket状态标记为已连接：', this.is_open_socket);
      this.start();
      console.log('启动心跳检测');
      // 注：只有连接正常打开中 ，才能正常收到消息
      this.socketTask.onMessage((e) => {
        // 字符串转json
        try {
          let res = JSON.parse(e.data);
          console.log('WebSocket收到消息：', res);
          if (res) {
            this.onMessage(res);
            // uni.$emit('getPositonsOrder', res);
          }
        } catch (error) {
          console.error('WebSocket消息解析错误：', error, e.data);
        }
      });
    });
    if (!this.init) {
      // 监听连接失败，这里代码我注释掉的原因是因为如果服务器关闭后，和下面的onclose方法一起发起重连操作，这样会导致重复连接
      this.socketTask.onError((res) => {
        console.error('WebSocket连接错误：', res);
        this.socketTask = null;
        this.is_open_socket = false;
        console.log('WebSocket状态标记为未连接：', this.is_open_socket);
        clearInterval(this.heartbeatInterval);
        clearInterval(this.reconnectTimeOut);
        if (!this.isClose) {
          console.log('WebSocket连接错误，准备重连，当前状态：', {
            isClose: this.isClose,
            connectNum: this.connectNum
          });
          this.traderDetailIndex = 2;
          this.reconnect();
          this.connectNum += 1;
        } else {
          console.log('WebSocket已手动关闭，不进行重连');
        }
      });
      this.init = true;
    }
    // 这里仅是事件监听【如果socket关闭了会执行】
    this.socketTask.onClose((err) => {
      console.info('WebSocket连接已关闭：', err);
      clearInterval(this.heartbeatInterval);
      clearInterval(this.reconnectTimeOut);
      this.is_open_socket = false;
      console.log('WebSocket状态标记为未连接：', this.is_open_socket);
      this.socketTask = null;
      if (!this.isClose) {
        console.log('WebSocket连接关闭，准备重连，当前状态：', {
          isClose: this.isClose,
          connectNum: this.connectNum
        });
        this.reconnect();
      } else {
        console.log('WebSocket连接关闭，不进行重连，当前状态：', {
          isClose: this.isClose,
          connectNum: this.connectNum
        });
        uni.$emit('connectError', { type: 'close', error: err });
        console.log('触发connectError事件：close');
        this.networkStatus = false;
        uni.onNetworkStatusChange(this.CALLBACK);
        console.log('开启网络状态监听');
        this.connectNum = 1;
      }
    });
  }
  // 主动关闭socket连接
  Close() {
    console.log('主动关闭WebSocket连接，当前状态：', {
      is_open_socket: this.is_open_socket,
      socketTask: !!this.socketTask
    });
    clearInterval(this.reconnectTimeOut);
    if (!this.is_open_socket) {
      console.log('WebSocket未连接，无需关闭');
      this.isClose = true;
      return;
    }
    this.socketTask.close({
      success: () => {
        console.log('WebSocket关闭成功');
        this.isClose = true;
        this.is_open_socket = false;
        console.log('WebSocket状态标记为未连接：', this.is_open_socket);
      },
      fail: (err) => {
        console.error('WebSocket关闭失败：', err);
        this.isClose = true;
      }
    });
  }
  onMessage() {} //发送消息
  send(data) {
    // 注：只有连接正常打开中 ，才能正常成功发送消息
    if (this.socketTask) {
      console.log('发送WebSocket消息：', data, '连接状态:', this.is_open_socket);
      this.socketTask.send({
        data: JSON.stringify(data),
        async success() {
          console.log('WebSocket消息发送成功:', data);
        },
        fail(err) {
          console.error('WebSocket消息发送失败：', err, '消息内容:', data);
        }
      });
    } else {
      console.error('WebSocket未连接，无法发送消息：', data, '连接状态:', this.is_open_socket);
    }
  }

  // 检测状态
  checkStatus() {
    const status = !(!this.socketTask || [2, 3].includes(this.socketTask.readyState));
    console.log('WebSocket连接状态检查：', {
      socketTask: !!this.socketTask,
      readyState: this.socketTask ? this.socketTask.readyState : 'null',
      status: status,
      is_open_socket: this.is_open_socket
    });
    if (!status) {
      console.info('WebSocket未连接！');
      return false;
    }
    console.info('WebSocket连接正常！');
    return true;
  }

  // 心跳检测
  start() {
    console.log('开启WebSocket心跳检测，间隔：', this.timeout, 'ms');
    this.heartbeatInterval = setInterval(() => {
      // 发送心跳，后端收到后返回一个心跳响应
      if (this.socketTask) {
        console.log('发送心跳包...', '连接状态:', this.is_open_socket);
        this.send({
          type: 'ping',
        });
      } else {
        console.log('WebSocket未连接，无法发送心跳包', '连接状态:', this.is_open_socket);
        // 断开重连
        if (!this.isClose) {
          console.log('准备重新连接WebSocket', '连接状态:', this.is_open_socket);
          this.reconnect();
        } else {
          console.log('WebSocket已手动关闭，不进行重连', '连接状态:', this.is_open_socket);
        }
      }
    }, this.timeout);
  }

  // 重连
  reconnect() {
    console.log('准备重连WebSocket，当前状态：', {
      isClose: this.isClose,
      is_open_socket: this.is_open_socket.value,
      connectNum: this.connectNum,
      networkStatus: this.networkStatus
    });
    // 停止发送心跳
    clearInterval(this.heartbeatInterval);
    console.log('已清除心跳检测定时器');
    // 如果不是人为关闭的话，进行重连
    if (!this.isClose) {
      console.log('第' + this.connectNum + '次重连，3秒后执行');
      this.reconnectTimeOut = setTimeout(() => {
        console.log('开始执行第' + this.connectNum + '次重连', '连接状态:', this.is_open_socket);
        this.connectSocketInit(this.data);
      }, 3000);
    } else if (!this.is_open_socket.value) {
      console.info('2秒后重新连接...');
      this.reconnectTimeOut = setInterval(() => {
        console.log('尝试重新连接WebSocket', '连接状态:', this.is_open_socket, '重连次数:', this.connectNum);
        this.connectSocketInit(this.data);
      }, 2000);
    } else {
      console.log('WebSocket已连接或已手动关闭，不进行重连', '连接状态:', this.is_open_socket);
    }
  }
  /**
   * @description 将 scoket 数据进行过滤
   * @param {array} array
   * @param {string} type 区分 弹窗 openposition 分为跟随和我的
   */
  arrayFilter(array, type = 'normal', signalId = 0) {
    let arr1 = [];
    let arr2 = [];
    let obj = {
      arr1: [],
      arr2: [],
    };
    arr1 = array.filter((v) => v.flwsig == true);
    arr2 = array.filter((v) => v.flwsig == false);
    if (type == 'normal') {
      if (signalId) {
        arr1 = array.filter((v) => v.flwsig == true && v.sigtraderid == signalId);
        return arr1;
      } else {
        return arr1.concat(arr2);
      }
    } else {
      if (signalId > 0) {
        arr1 = array.filter((v) => v.flwsig == true && v.sigtraderid == signalId);
        obj.arr1 = arr1;
      } else {
        obj.arr1 = arr1;
      }
      obj.arr2 = arr2;

      return obj;
    }
  }
}
export default socketIO;
